﻿using System;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;


using Chilkat;


namespace Cybertron_Tracker.Cybertron
{
    public class RedMine
    {
        public static String RootAddress = "http://dev.offstage.us/";
        public static String DateFormat = "dd-MM-yyyy HH:mm tt";

        private static Boolean Authenticated;

        private static String Username;
        private static String Email;
        private static String Password;

        private static Hashtable activity;
        
        private static Hashtable projects;
        private static Hashtable issues;
        private static Issue currentIssue;

        public static Boolean isAuthenticated()
        {
            String content = W3Request.Download(RootAddress);
            return indexOfLoginForm(content);
        }

        public static Boolean isAuthenticated(String RequestOutput)
        {
            Authenticated = indexOfLoginForm(RequestOutput);
            return Authenticated;
        }

        private static Boolean indexOfLoginForm(String content)
        {
            //if login form has found, user is not authenticated
            return !(content.IndexOf("<form action=\"/login\" method=\"post\">") > 0);
        }

        public static Hashtable login(String User, String Pass)
        {
            Username = User;
            Password = Pass;

            W3Request.Clear();
            W3Request.AddField("username",Username);
            W3Request.AddField("password",Password);
            W3Request.AddField("back_url", RootAddress + "my/account");
            W3Request.AddField("login", "Login");
            String responseHtml = W3Request.Post(RootAddress + "login");

            
            Hashtable responseData = new Hashtable();
            
            String error = Html.getContentBetweenString(responseHtml, "<div class=\"flash error\">", "</div>");
            if (error != null) responseData.Add("error", error);
            
            String userEmail = Html.getContentBetweenString(responseHtml, "<input id=\"user_mail\" name=\"user[mail]\" size=\"30\" type=\"text\" value=\"", "\" />");
            if (userEmail != null) Email = userEmail;

            return responseData;
        }

        public static Hashtable getProjects()
        {
            if (projects == null) projects = new Hashtable();
            else projects.Clear();

            String projectsContent = W3Request.Download(RootAddress + "projects");
            //Xml xmlProjects = RedMine.getXml("projects?format=atom");
            String projectsSelect = "<projects>" + Html.getContentBetweenString(projectsContent, "<option disabled=\"disabled\">---</option>", "</select>") + "</projects>";
            
            Xml xmlProjects = xmlConvert(projectsSelect);
            for (int i = 0; i < xmlProjects.NumChildren; i++)
            {
                Xml option = xmlProjects.GetChild(i);
                Project project = new Project();
                project.setName(option.Content);
                project.setId(Html.getContentBetweenString(option.GetAttrValue("value"), "/projects/show/", "?jump"));
                project.clearIssues();

                projects.Add(project.name, project);
            }

            /*for (int i = 0; i < xmlProjects.NumChildren; i++)
            {
            
                Xml entry = xmlProjects.GetChild(i);
                if (entry.Tag == "entry")
                {
                    Project project = new Project();
                    project.setName(entry.GetChildContent("title"));
                    project.setDate(entry.GetChildContent("updated"));
                    project.setLink(entry.GetChildContent("id"));
                    project.clearIssues();

                    projects.Add(project.name, project);
                }
            }*/

            if (issues == null) issues = new Hashtable();
            else issues.Clear();

            Xml xmlIssues = RedMine.getXml("issues?format=atom");
            
            String firstIssueLink = null;

            for (int i = 0; i < xmlIssues.NumChildren; i++)
            {

                Xml entry = xmlIssues.GetChild(i);
                if (entry.Tag == "entry")
                {
                    Issue issue = new Issue();
                    issue.setName(entry.GetChildContent("title"));
                    issue.setDate(entry.GetChildContent("updated"));
                    issue.setContent(entry.GetChildContent("content"));
                    issue.setLink(entry.GetChildContent("id"));
                    
                    firstIssueLink = issue.link;

                    ((Project)projects[issue.project]).addIssue(issue);
                    issues.Add(issue.name, issue);
                }
            }

            if (activity == null) activity = new Hashtable();
            else activity.Clear();

            if (firstIssueLink != null)
            {
                String activityContent = W3Request.Download(firstIssueLink);
                String activities = Html.getContentBetweenString(activityContent, "name=\"time_entry[activity_id]\">", "</select>");
                activities = "<activities>" + activities + "</activities>";
                Xml activitiesParse = xmlConvert(activities);

                for (int i = 0; i < activitiesParse.NumChildren; i++)
                {
                    Xml option = activitiesParse.GetChild(i);

                    String value = option.GetAttrValue("value");
                    if (value != "")
                    {
                        Activity newActivity = new Activity();
                        newActivity.setName(option.Content);
                        newActivity.setValue(value);
                        activity.Add(option.Content, newActivity);
                    }
                }

            }

            return projects;
        }

        public static Hashtable getIssues(String projectName)
        {
            if (projectName == "All")
            {
                return issues;
            } else {
                return ((Project)projects[projectName]).issues;
            }
        }

        public static Issue selectIssue(String name)
        {
            if (name != "None") currentIssue = (Issue)issues[name];
            else currentIssue = null;

            return currentIssue;
        }

        public static Boolean hasIssueSelected()
        {
            return currentIssue != null;
        }

        private static Xml getXml(String url)
        {
            W3Request.Clear();
            String xmlContent = W3Request.Download(RootAddress + url);
            return xmlConvert(xmlContent);
        }

        private static Xml xmlConvert(String content)
        {
            Xml xml = new Xml();
            xml.LoadXml(content);
            return xml;
        }

        public static Hashtable getActivityList()
        {
            return activity;
        }

        public static void getRecentActivity()
        {
            //fetch on "projects/activity?format=atom"
        }

        public static void startLog()
        {
            currentIssue.startLog();
        }

        public static void endLog(String comment, String activityIdx)
        {
            float loggedHours = currentIssue.endLog();

            //if have more than 1 minute...
            if (loggedHours >= 0.01)
            {
                String projectId = ((Project)projects[currentIssue.project]).id;

                W3Request.Clear();
                W3Request.AddField("time_entry[hours]", loggedHours.ToString());
                W3Request.AddField("time_entry[comments]", comment);
                W3Request.AddField("time_entry[activity_id]", ((Activity)activity[activityIdx]).id);
                String responseHtml = W3Request.Post(RootAddress + "issues/edit/" + currentIssue.id);

                if (W3Request.getStatus() == HttpStatusCode.OK)
                {
                    currentIssue.clearHours();
                }
            }
        }

    }
}
